﻿#pragma once

#include "Packet.h"
#include "Enums.h"
#include "Data/ItemData.h"
#include "Data/IntelligentCreatureData.h"
#include <string>
#include <vector>

namespace ClientPackets
{
    class ClientVersion final : public Packet
    {
    public:
        short getIndex() const override;

        std::vector<unsigned char> VersionHash;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Disconnect final : public Packet
    {
    public:
        short getIndex() const override;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class KeepAlive final : public Packet
    {
    public:
        short getIndex() const override;
        long long Time = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class NewAccount final : public Packet
    {
    public:
        short getIndex() const override;

        std::string AccountID = std::string::Empty;
        std::string Password = std::string::Empty;
        DateTime BirthDate;
        std::string UserName = std::string::Empty;
        std::string SecretQuestion = std::string::Empty;
        std::string SecretAnswer = std::string::Empty;
        std::string EMailAddress = std::string::Empty;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class ChangePassword final : public Packet
    {
    public:
        short getIndex() const override;

        std::string AccountID = std::string::Empty;
        std::string CurrentPassword = std::string::Empty;
        std::string NewPassword = std::string::Empty;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Login final : public Packet
    {
    public:
        short getIndex() const override;

        std::string AccountID = std::string::Empty;
        std::string Password = std::string::Empty;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class NewCharacter final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Name = std::string::Empty;
        MirGender Gender = static_cast<MirGender>(0);
        MirClass Class = static_cast<MirClass>(0);
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class DeleteCharacter final : public Packet
    {
    public:
        short getIndex() const override;

        int CharacterIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class StartGame final : public Packet
    {
    public:
        short getIndex() const override;

        int CharacterIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class LogOut final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Turn final : public Packet
    {
    public:
        short getIndex() const override;

        MirDirection Direction = static_cast<MirDirection>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Walk final : public Packet
    {
    public:
        short getIndex() const override;

        MirDirection Direction = static_cast<MirDirection>(0);
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Run final : public Packet
    {
    public:
        short getIndex() const override;

        MirDirection Direction = static_cast<MirDirection>(0);
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Chat final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Message = std::string::Empty;
        std::vector<ChatItem*> LinkedItems = std::vector<ChatItem*>();

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };
    class MoveItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType Grid = static_cast<MirGridType>(0);
        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class StoreItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class DepositRefineItem final : public Packet
    {

    public:
        short getIndex() const override;

        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class RetrieveRefineItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class RefineCancel final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class RefineItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class CheckRefine final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class ReplaceWedRing final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };


    class DepositTradeItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class RetrieveTradeItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class TakeBackItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MergeItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType GridFrom = static_cast<MirGridType>(0), GridTo = static_cast<MirGridType>(0);
        unsigned long long IDFrom = 0, IDTo = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class EquipItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType Grid = static_cast<MirGridType>(0);
        unsigned long long UniqueID = 0;
        int To = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class RemoveItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType Grid = static_cast<MirGridType>(0);
        unsigned long long UniqueID = 0;
        int To = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class RemoveSlotItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType Grid = static_cast<MirGridType>(0);
        MirGridType GridTo = static_cast<MirGridType>(0);
        unsigned long long UniqueID = 0;
        int To = 0;
        unsigned long long FromUniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class SplitItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType Grid = static_cast<MirGridType>(0);
        unsigned long long UniqueID = 0;
        unsigned short Count = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class UseItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class DropItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        unsigned short Count = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class DropGold final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int Amount = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class PickUp final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Inspect final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int ObjectID = 0;
        bool Ranking = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };
    class ChangeAMode final : public Packet
    {
    public:
        short getIndex() const override;

        AttackMode Mode = static_cast<AttackMode>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class ChangePMode final : public Packet
    {
    public:
        short getIndex() const override;

        PetMode Mode = static_cast<PetMode>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class ChangeTrade final : public Packet
    {
    public:
        short getIndex() const override;

        bool AllowTrade = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Attack final : public Packet
    {
    public:
        short getIndex() const override;

        MirDirection Direction = static_cast<MirDirection>(0);
        Spell Spell = static_cast<Spell>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class RangeAttack final : public Packet //ArcherTest
    {
    public:
        virtual ~RangeAttack()
        {
            delete Location;
            delete TargetLocation;
        }

        short getIndex() const override;

        MirDirection Direction = static_cast<MirDirection>(0);
        Point *Location;
        unsigned int TargetID = 0;
        Point *TargetLocation;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Harvest final : public Packet
    {
    public:
        short getIndex() const override;

        MirDirection Direction = static_cast<MirDirection>(0);
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class CallNPC final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int ObjectID = 0;
        std::string Key = std::string::Empty;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class BuyItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long ItemIndex = 0;
        unsigned short Count = 0;
        PanelType Type = static_cast<PanelType>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class SellItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        unsigned short Count = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class CraftItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        unsigned short Count = 0;
        std::vector<int> Slots;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class RepairItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class BuyItemBack final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        unsigned short Count = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class SRepairItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MagicKey final : public Packet
    {
    public:
        short getIndex() const override;

        Spell Spell = static_cast<Spell>(0);
        unsigned char Key = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class Magic final : public Packet
    {
    public:
        virtual ~Magic()
        {
            delete Location;
        }

        short getIndex() const override;

        Spell Spell = static_cast<Spell>(0);
        MirDirection Direction = static_cast<MirDirection>(0);
        unsigned int TargetID = 0;
        Point *Location;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class SwitchGroup final : public Packet
    {
    public:
        short getIndex() const override;

        bool AllowGroup = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class AddMember final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Name = std::string::Empty;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class DelMember final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Name = std::string::Empty;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GroupInvite final : public Packet
    {
    public:
        short getIndex() const override;

        bool AcceptInvite = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class MarriageRequest final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class MarriageReply final : public Packet
    {
    public:
        short getIndex() const override;

        bool AcceptInvite = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class ChangeMarriage final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class DivorceRequest final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class DivorceReply final : public Packet
    {
    public:
        short getIndex() const override;

        bool AcceptInvite = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AddMentor final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Name;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class MentorReply final : public Packet
    {
    public:
        short getIndex() const override;

        bool AcceptInvite = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AllowMentor final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class CancelMentor final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };


    class TradeReply final : public Packet
    {
    public:
        short getIndex() const override;

        bool AcceptInvite = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class TradeRequest final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class TradeGold final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int Amount = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class TradeConfirm final : public Packet
    {
    public:
        short getIndex() const override;

        bool Locked = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class TradeCancel final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class TownRevive final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class SpellToggle final : public Packet
    {
    public:
        short getIndex() const override;
        Spell Spell = static_cast<Spell>(0);
        bool CanUse = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class ConsignItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        unsigned int Price = 0;
        MarketPanelType Type = static_cast<MarketPanelType>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MarketSearch final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Match = std::string::Empty;
        ItemType Type = (ItemType)0;
        bool Usermode = false;
        short MinShape = 0, MaxShape = 5000;
        MarketPanelType MarketType = MarketPanelType::Market;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MarketRefresh final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MarketPage final : public Packet
    {
    public:
        short getIndex() const override;
        int Page = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MarketBuy final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long AuctionID = 0;
        unsigned int BidPrice = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MarketSellNow final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long AuctionID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class MarketGetBack final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long AuctionID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class RequestUserName final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int UserID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };
    class RequestChatItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long ChatItemID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class EditGuildMember final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned char ChangeType = 0;
        unsigned char RankIndex = 0;
        std::string Name = "";
        std::string RankName = "";

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class EditGuildNotice final : public Packet
    {
    public:
        short getIndex() const override;

        std::vector<std::string> notice = std::vector<std::string>();

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GuildInvite final : public Packet
    {
    public:
        short getIndex() const override;

        bool AcceptInvite = false;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class RequestGuildInfo final : public Packet
    {
    public:
        short getIndex() const override;
        unsigned char Type = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GuildNameReturn final : public Packet
    {
    public:
        short getIndex() const override;
        std::string Name;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GuildWarReturn final : public Packet
    {
    public:
        short getIndex() const override;
        std::string Name;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GuildStorageGoldChange final : public Packet
    {
    public:
        short getIndex() const override;
        unsigned char Type = 0;
        unsigned int Amount = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GuildStorageItemChange final : public Packet
    {
    public:
        short getIndex() const override;
        unsigned char Type = 0;
        int From = 0, To = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class EquipSlotItem final : public Packet
    {
    public:
        short getIndex() const override;

        MirGridType Grid = static_cast<MirGridType>(0);
        unsigned long long UniqueID = 0;
        int To = 0;
        MirGridType GridTo = static_cast<MirGridType>(0);
        unsigned long long ToUniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class FishingCast final : public Packet
    {
    public:
        short getIndex() const override;

        bool CastOut = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class FishingChangeAutocast final : public Packet
    {
    public:
        short getIndex() const override;

        bool AutoCast = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AcceptQuest final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int NPCIndex = 0;
        int QuestIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class FinishQuest final : public Packet
    {
    public:
        short getIndex() const override;

        int QuestIndex = 0;
        int SelectedItemIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AbandonQuest final : public Packet
    {
    public:
        short getIndex() const override;

        int QuestIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class ShareQuest final : public Packet
    {
    public:
        short getIndex() const override;

        int QuestIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AcceptReincarnation final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class CancelReincarnation final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class CombineItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long IDFrom = 0, IDTo = 0;
    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AwakeningNeedMaterials final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        AwakeType Type = static_cast<AwakeType>(0);

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class AwakeningLockedItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        bool Locked = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class Awakening final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        AwakeType Type = static_cast<AwakeType>(0);
        unsigned int PositionIdx = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class DisassembleItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class DowngradeAwakening final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class ResetAddedItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class SendMail final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Name;
        std::string Message;
        unsigned int Gold = 0;
        std::vector<unsigned long long> ItemsIdx = std::vector<unsigned long long>(5);
        bool Stamped = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class ReadMail final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long MailID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class CollectParcel final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long MailID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class DeleteMail final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long MailID = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class LockMail final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long MailID = 0;
        bool Lock = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class MailLockedItem final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned long long UniqueID = 0;
        bool Locked = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class MailCost final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int Gold = 0;
        std::vector<unsigned long long> ItemsIdx = std::vector<unsigned long long>(5);
        bool Stamped = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class RequestIntelligentCreatureUpdates final : public Packet
    {
    public:
        short getIndex() const override;

        bool Update = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class UpdateIntelligentCreature final : public Packet
    {
    public:
        virtual ~UpdateIntelligentCreature()
        {
            delete Creature;
        }

        short getIndex() const override;


        ClientIntelligentCreature *Creature;
        bool SummonMe = false;
        bool UnSummonMe = false;
        bool ReleaseMe = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class IntelligentCreaturePickup final : public Packet
    {
    public:
        virtual ~IntelligentCreaturePickup()
        {
            delete Location;
        }

        short getIndex() const override;

        bool MouseMode = false;
        Point *Location = new Point(0,0);

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class AddFriend final : public Packet
    {
    public:
        short getIndex() const override;

        std::string Name;
        bool Blocked = false;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class RemoveFriend final : public Packet
    {
    public:
        short getIndex() const override;

        int CharacterIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class RefreshFriends final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };


    class AddMemo final : public Packet
    {
    public:
        short getIndex() const override;

        int CharacterIndex = 0;
        std::string Memo;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class GuildBuffUpdate final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned char Action = 0; //0 = request list, 1 = request a buff to be enabled, 2 = request a buff to be activated
        int Id = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class GameshopBuy final : public Packet
    {
    public:
        short getIndex() const override;

        int GIndex = 0;
        unsigned char Quantity = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class NPCConfirmInput final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int NPCID = 0;
        std::string PageName;
        std::string Value;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };

    class ReportIssue final : public Packet
    {
    public:
        short getIndex() const override;

        std::vector<unsigned char> Image;
        int ImageSize = 0;
        int ImageChunk = 0;

        std::string Message;

    protected:
        void ReadPacket(BinaryReader *reader) override;
        void WritePacket(BinaryWriter *writer) override;
    };
    class GetRanking final : public Packet
    {
    public:
        short getIndex() const override;
        unsigned char RankIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class Opendoor final : public Packet
    {
    public:
        short getIndex() const override;
        unsigned char DoorIndex = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class GetRentedItems final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class ItemRentalRequest final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class ItemRentalFee final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int Amount = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class ItemRentalPeriod final : public Packet
    {
    public:
        short getIndex() const override;

        unsigned int Days = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class DepositRentalItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class RetrieveRentalItem final : public Packet
    {
    public:
        short getIndex() const override;

        int From = 0, To = 0;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class CancelItemRental final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class ItemRentalLockFee final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class ItemRentalLockItem final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };

    class ConfirmItemRental final : public Packet
    {
    public:
        short getIndex() const override;

    protected:
        void ReadPacket(BinaryReader *reader) override;

        void WritePacket(BinaryWriter *writer) override;
    };
}
